package com.tjs.lucky.domain.activity.service.partake;

import com.tjs.lucky.common.Ids;
import com.tjs.lucky.common.ResponseCode;
import com.tjs.lucky.common.Result;
import com.tjs.lucky.domain.activity.model.req.PartakeReq;
import com.tjs.lucky.domain.activity.model.res.PartakeResult;
import com.tjs.lucky.domain.activity.model.vo.ActivityBillVO;
import com.tjs.lucky.domain.activity.model.vo.ActivityVO;
import com.tjs.lucky.domain.activity.model.vo.UserTakeActivityVO;
import com.tjs.lucky.domain.activity.repository.IActivityRepository;
import com.tjs.lucky.domain.support.ids.DefindeIdGenerator;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @Author: 田佳澍
 * @Description:
 * @DateTime: 2023/5/25 16:15
 **/
public abstract class BaseActivityPartake extends ActivityPartakeSupport implements IActivityPartake {

    @Resource
    private Map<Ids, DefindeIdGenerator> idGeneratorMap;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public PartakeResult queryActivityRecord(PartakeReq req){
        // 1. 查询是否存在未执行抽奖领取活动单【user_take_activity 存在 state = 0，领取了但抽奖过程失败的，可以直接返回领取结果继续抽奖】
        UserTakeActivityVO userTakeActivityVO = this.queryNoConsumedTakeActivityOrder(req.getActivityId(), req.getUId());
        if(userTakeActivityVO == null){
            return null;
        }
        //校验活动信息
        ActivityVO activityVO = activityRepository.queryActivityInfo(userTakeActivityVO.getActivityId());
        ActivityBillVO activityBillVO = new ActivityBillVO();
        activityBillVO.setBeginDateTime(activityVO.getBeginDateTime());
        activityBillVO.setEndDateTime(activityVO.getEndDateTime());
        activityBillVO.setStockSurplusCount(activityBillVO.getStockSurplusCount());
        activityBillVO.setState(activityVO.getState()); // 活动状态
        activityBillVO.setUserTakeLeftCount(userTakeActivityVO.getUserTakeLeftCount());

        Result checkResult = this.checkActivityBill(req, activityBillVO);
        if (!ResponseCode.SUCCESS.getCode().equals(checkResult.getCode())) {
            return null;
        }
        return buildPartakeResult(userTakeActivityVO, ResponseCode.SUCCESS);
    }

    @Override
    public PartakeResult doPartake(PartakeReq req) {

        // 1. 查询活动账单
        ActivityBillVO activityBillVO = super.queryActivityBill(req);

        // 2. 活动信息校验处理【活动库存、状态、日期、个人参与次数】
        Result checkResult = this.checkActivityBill(req, activityBillVO);
        if (!ResponseCode.SUCCESS.getCode().equals(checkResult.getCode())) {
            return new PartakeResult(checkResult.getCode(), checkResult.getInfo());
        }
        // 3. 活动记录
        Long takeId = idGeneratorMap.get(Ids.SnowFlake).nextId();
        Result grabResult = this.savePartRecord(req, activityBillVO, takeId);
        if (!ResponseCode.SUCCESS.getCode().equals(grabResult.getCode())) {
            return new PartakeResult(grabResult.getCode(), grabResult.getInfo());
        }
        return buildPartakeResult(activityBillVO.getStrategyId(), takeId, ResponseCode.SUCCESS, activityBillVO);
    }

    /**
     * 封装结果【返回的策略ID，用于继续完成抽奖步骤】
     *
     * @param strategyId 策略ID
     * @param takeId     领取ID
     * @param code       状态码
     * @return 封装结果
     */
    private PartakeResult buildPartakeResult(Long strategyId, Long takeId, ResponseCode code, ActivityBillVO activityBillVO) {
        PartakeResult partakeResult = new PartakeResult(code.getCode(), code.getInfo());
        partakeResult.setStrategyId(strategyId);
        partakeResult.setTakeId(takeId);
        partakeResult.setActivityLeftPartCount(activityBillVO.getStockSurplusCount());
        return partakeResult;
    }

    private PartakeResult buildPartakeResult(UserTakeActivityVO userTakeActivityVO, ResponseCode code) {
        PartakeResult partakeResult = new PartakeResult(code.getCode(), code.getInfo());
        partakeResult.setStrategyId(userTakeActivityVO.getStrategyId());
        partakeResult.setTakeId(userTakeActivityVO.getTakeId());
        partakeResult.setActivityLeftPartCount(userTakeActivityVO.getActivityLeftPartCount());
        return partakeResult;
    }

    /**
     * 查询是否存在未执行抽奖领取活动单【user_take_activity 存在 state = 0，领取了但抽奖过程失败的，可以直接返回领取结果继续抽奖】
     *
     * @param activityId 活动ID
     * @param uId        用户ID
     * @return 领取单
     */
    public abstract UserTakeActivityVO queryNoConsumedTakeActivityOrder(Long activityId, String uId);

    /**
     * 活动信息校验处理，把活动库存、状态、日期、个人参与次数
     *
     * @param partake 参与活动请求
     * @param bill    活动账单
     * @return 校验结果
     */
    public abstract Result checkActivityBill(PartakeReq partake, ActivityBillVO bill);

    /**
     * 记录活动
     *
     * @param partake 参与活动请求
     * @param bill    活动账单
     * @param takeId  领取活动ID
     * @return 领取结果
     */
    public abstract Result savePartRecord(PartakeReq partake, ActivityBillVO bill, Long takeId);


}
